

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

public class Page<E> extends ArrayList<E> implements Closeable {

	private static final long serialVersionUID = 1L;

	// 页码，从1开始
	@Getter
	private int pageNum;

	// 页面大小
	@Getter
	@Setter
	private int pageSize;

	// 起始行
	@Getter
	@Setter
	private int startRow;

	// 末行
	@Getter
	@Setter
	private int endRow;

	// 总数
	@Getter
	private long total;

	// 总页数
	@Getter
	@Setter
	private int pages;

	// 分页合理化
	@Getter
	private boolean reasonable;

	// 当设置为 true 的时候，如果 pagesize 设置为 0（或 RowBounds 的 limit=0），就不执行分页，返回全部结果
	@Getter
	@Setter
	private boolean pageSizeZero;

	public Page() {
		super();
	}

	public Page(int pageNum, int pageSize) {
		this(pageNum, pageSize, false);
	}

	private Page(int pageNum, int pageSize, boolean reasonable) {
		super(0);
		if (pageNum == 1 && pageSize == Integer.MAX_VALUE) {
			pageSizeZero = true;
			pageSize = 0;
		}
		this.pageNum = pageNum;
		this.pageSize = pageSize;
		calculateStartAndEndRow();
		setReasonable(reasonable);
	}

	/**
	 * int[] rowBounds 
	 * rowBounds[0] : offset 
	 * rowBounds[1] : limit
	 */
	public Page(int[] rowBounds) {
		super(0);
		int offset = rowBounds[0];
		int limit = rowBounds[1];
		if (offset == 0 && limit == Integer.MAX_VALUE) {
			pageSizeZero = true;
			this.pageSize = 0;
		} else {
			this.pageSize = limit;
			this.pageNum = limit != 0 ? (int) (Math.ceil(((double) offset + limit) / limit)) : 0;
		}
		this.startRow = offset;
		this.endRow = this.startRow + limit;
	}

	public List<E> getResult() {
		return this;
	}

	public Page<E> setPageNum(int pageNum) {
		// 分页合理化，针对不合理的页码自动处理
		this.pageNum = (reasonable == true && pageNum <= 0) ? 1 : pageNum;
		return this;
	}

	public void setTotal(long total) {
		this.total = total;
		if (total < 0) {
			pages = 1;
			return;
		}

		if (pageSize > 0) {
			pages = (int) (total / pageSize + ((total % pageSize == 0) ? 0 : 1));
		} else {
			pages = 0;
		}

		// 分页合理化，针对不合理的页码自动处理
		if (reasonable == true && pageNum > pages) {
			if (pages != 0) {
				pageNum = pages;
			}
			calculateStartAndEndRow();
		}
	}

	public void setReasonable(boolean reasonable) {
		this.reasonable = reasonable;

		// 分页合理化，针对不合理的页码自动处理
		if (this.reasonable == true && this.pageNum <= 0) {
			this.pageNum = 1;
			calculateStartAndEndRow();
		}
	}

	/**
	 * 计算起止行号
	 */
	private void calculateStartAndEndRow() {
		this.startRow = this.pageNum > 0 ? (this.pageNum - 1) * this.pageSize : 0;
		this.endRow = this.startRow + this.pageSize * (this.pageNum > 0 ? 1 : 0);
	}

	/**
	 * 设置页码
	 */
	public Page<E> setpageNum(int pageNum) {
		// 分页合理化，针对不合理的页码自动处理
		this.pageNum = (reasonable == true && pageNum <= 0) ? 1 : pageNum;
		return this;
	}

	/**
	 * 设置页面大小
	 */
	public Page<E> pageSize(int pageSize) {
		this.pageSize = pageSize;
		calculateStartAndEndRow();
		return this;
	}

	/**
	 * 设置合理化
	 */
	public Page<E> reasonable(boolean reasonable) {
		setReasonable(reasonable);
		return this;
	}

	/**
	 * 当设置为 true 的时候，如果 pagesize 设置为 0（或 RowBounds 的 limit=0），就不执行分页，返回全部结果
	 */
	public Page<E> pageSizeZero(boolean pageSizeZero) {
		setPageSizeZero(pageSizeZero);
		return this;
	}

	@Override
	public String toString() {
		return "Page{" 
				+ ", pageNum=" + pageNum 
				+ ", pageSize=" + pageSize 
				+ ", startRow=" + startRow 
				+ ", endRow=" + endRow 
				+ ", total=" + total 
				+ ", pages=" + pages 
				+ ", reasonable=" + reasonable 
				+ ", pageSizeZero=" + pageSizeZero 
				+ '}' 
				+ super.toString();
	}

	@Override
	public void close() throws IOException {
		this.clear();
	}
}
